package com.hay.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hay.common.PageResult;
import com.hay.item.bo.SpuBo;
import com.hay.item.mapper.*;
import com.hay.item.pojo.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @title: GoodsService
 * @Author HuangYan
 * @Date: 2020/7/22 21:44
 * @Version 1.0
 */
@Service
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;

    /**
     * 查询商品信息
     * @param key
     * @param saleable
     * @param page
     * @param rows
     * @return
     */
    public PageResult<SpuBo> querySpuByPage(String key, Boolean saleable, Integer page, Integer rows) {

        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        // 添加查询条件
        if (StringUtils.isNotBlank(key)){
            criteria.andLike("title", "%" + key + "%");
        }
        // 筛选上架与否
        criteria.andEqualTo("saleable", saleable);
        // 开启分页
        PageHelper.startPage(page, rows);
        // 执行查询
        List<Spu> spus = spuMapper.selectByExample(example);
        PageInfo<Spu> pageInfo = new PageInfo<>(spus);
        // 转换查询结果为SpuBo,并查询category与brand
        List<SpuBo> spuBoList = spus.stream().map(spu -> { // 遍历每一个Spu并将其中category和brand字段查询出来
            SpuBo spuBo = new SpuBo();
            // 将查询出来的spu对象的字段复制给spuBo
            BeanUtils.copyProperties(spu, spuBo);
            // 根据id1,id2,id3 查询出商品分类cname
            List<String> list = categoryService.queryCategoryByCid123(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
            String cname = StringUtils.join(list, "-");
            spuBo.setCname(cname);
            // 查询商品brand
            Brand brand = brandMapper.selectByPrimaryKey(spu.getBrandId());
            spuBo.setBname(brand.getName());
            return spuBo;
        }).collect(Collectors.toList());
        // 封装PageResult
        return new PageResult<SpuBo>(pageInfo.getTotal(), spuBoList);
    }

    /**
     *  新增商品信息
     * @param spuBo
     */
    @Transactional
    public void addGoods(SpuBo spuBo) {

        spuBo.setId(null);      // 防止模拟请求，注入数据
        spuBo.setSaleable(true);    // 设置上架
        spuBo.setValid(true);       // 未删除
        spuBo.setCreateTime(new Date());    //创建时间
        spuBo.setLastUpdateTime(spuBo.getCreateTime());     //修改时间
        // 新增spu
        spuMapper.insertSelective(spuBo);
        // 新增spuDetail
        SpuDetail spuDetail = spuBo.getSpuDetail();
        spuDetail.setSpuId(spuBo.getId());
        spuDetailMapper.insertSelective(spuDetail);
        // 循环遍历sku集合
        addSkuListAndStock(spuBo);

        // 发送消息
        sendMessage("insert", spuBo.getId());
    }



    /**
     * 根据商品id查询商品信息
     * @param spuId
     * @return
     */
    public SpuDetail querySpuDetailBySpuId(Long spuId) {
        return spuDetailMapper.selectByPrimaryKey(spuId);
    }

    /**
     * 根据商品id查询sku集合
     * @param spuId
     * @return
     */
    public List<Sku> querySkuListBySpuId(Long spuId) {
        Sku record = new Sku();
        record.setSpuId(spuId);
        List<Sku> skus = skuMapper.select(record);
        // 遍历sku并查询库存信息stock
        skus.forEach(sku -> {
            Stock stock = stockMapper.selectByPrimaryKey(sku.getId());
            sku.setStock(stock.getStock());
        } );
        return skus;
    }

    /**
     * 修改商品信息
     * @param spuBo
     * @return
     */
    public void editGoods(SpuBo spuBo) {

        // 根据spuId查询所有的sku
        Sku record = new Sku();
        record.setSpuId(spuBo.getId());
        List<Sku> skus = skuMapper.select(record);

        // 删除库存信息
        skus.forEach(sku -> {
            stockMapper.deleteByPrimaryKey(sku.getId());
        });

        // 删除sku
        Sku sku = new Sku();
        sku.setSpuId(spuBo.getId());
        skuMapper.delete(sku);
        // 新增sku
        // 新增库存信息
        addSkuListAndStock(spuBo);

        // 更新spu
        spuBo.setSaleable(null);        // 不应该在此修改上下架
        spuBo.setValid(null);           // 不应该修改是否已删除
        spuBo.setCreateTime(null);      // 不能修改商品创建时间
        spuBo.setLastUpdateTime(new Date());    // 更新时间由后端决定
        spuMapper.updateByPrimaryKeySelective(spuBo);

        // 更新spuDetail
        spuDetailMapper.updateByPrimaryKeySelective(spuBo.getSpuDetail());

        // 发送消息
        sendMessage("update", spuBo.getId());
    }

    private void addSkuListAndStock(SpuBo spuBo) {
        spuBo.getSkus().forEach(sku -> {
            // 新增sku
            sku.setSpuId(spuBo.getId());
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(sku.getCreateTime());
            skuMapper.insertSelective(sku);
            // 新增stock
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
            stockMapper.insertSelective(stock);
        });
    }

    /**
     * 根据spuId查询spu
     * @param id
     * @return
     */
    public Spu querySpuById(Long id) {
        return spuMapper.selectByPrimaryKey(id);
    }

    /**
     * RabbitMQ 发送消息
     * @param type
     * @param id
     */
    public void sendMessage(String type, Long id){
        try {
            // 发送消息
            amqpTemplate.convertAndSend("leyou.item."+type,id);
        } catch (AmqpException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据skuId查询sku
     * @param skuId
     * @return
     */
    public Sku getSkuBySkuId(Long skuId) {
        return skuMapper.selectByPrimaryKey(skuId);
    }
}
